package com.lswms.service.impl;

import com.lswms.common.exception.ErrorCode;
import com.lswms.common.exception.RenException;
import com.lswms.common.service.impl.CrudServiceImpl;
import com.lswms.common.utils.ConvertUtils;
import com.lswms.common.utils.MoneyUtil;
import com.lswms.common.utils.ZqDateUtil;
import com.lswms.dao.YnSignDao;
import com.lswms.dto.YnSignDTO;
import com.lswms.dto.vo.req.QuerySignInfoReq;
import com.lswms.dto.vo.req.SignReq;
import com.lswms.dto.vo.resp.BeatSignResp;
import com.lswms.dto.vo.resp.QuerySignDetailResp;
import com.lswms.dto.vo.resp.QuerySignResp;
import com.lswms.entity.YnLotteryTicketOrderEntity;
import com.lswms.entity.YnSignEntity;
import com.lswms.entity.YnSignRecordEntity;
import com.lswms.entity.YnUserEntity;
import com.lswms.service.YnPayRecordService;
import com.lswms.service.YnSignRecordService;
import com.lswms.service.YnSignService;
import com.lswms.service.YnUserService;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

/**
 * 挑战期数表
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0 2020-05-06
 */
@Service
@Slf4j
public class YnSignServiceImpl extends CrudServiceImpl<YnSignDao, YnSignEntity, YnSignDTO> implements YnSignService {

	
	private static final YnSignDTO detailResp = null;

	@Autowired
	private YnSignRecordService ynSignRecordService;
	
	@Autowired
	private YnUserService ynUserService;
	
	@Autowired
	private YnPayRecordService ynPayRecordService;


	
    @Override
    public QueryWrapper<YnSignEntity> getWrapper(Map<String, Object> params){
    	Long id = (Long)params.get("id");
        String signNo = (String)params.get("signNo");
        String type = (String)params.get("type");
        

        QueryWrapper<YnSignEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(id != null, "id", id);
        wrapper.eq(StringUtils.isNotBlank(signNo), "sign_no", signNo);
        wrapper.eq(StringUtils.isNotBlank(type), "type", type);

        return wrapper;
    }
    /**
     * 添加期数
     */
	@Override
	public void createSign(YnSignEntity dto) {
		log.info("添加期数：{}",JSON.toJSONString(dto));
		//查询期数
		QueryWrapper<YnSignEntity> wrapper = new QueryWrapper<YnSignEntity>();
		wrapper.eq(StringUtils.isNotBlank(dto.getSignNo()), "sign_no", dto.getSignNo());
		wrapper.eq(StringUtils.isNotBlank(dto.getType()), "type", dto.getType());
		List<YnSignEntity> sign = baseDao.selectList(wrapper);
		if(sign.size() <= 0){
			//添加期数
			baseDao.insert(dto);
		}
	}
	/**
	 * 期数列表
	 */
	@Override
	public List<QuerySignResp> querySign() {
		//期数
		String year = ZqDateUtil.yyyyMMdd(ZqDateUtil.getNow());
		log.info("期数列表：{}",year);
		//返回结构
		List<QuerySignResp> list = new ArrayList<QuerySignResp>();
		//查询期数列表
		QueryWrapper<YnSignEntity> wrapper = new QueryWrapper<YnSignEntity>();
		wrapper.eq(StringUtils.isNotBlank(year), "sign_no", year);
		List<YnSignEntity> sign = baseDao.selectList(wrapper);
		for(YnSignEntity signEntity : sign){
			QuerySignResp resp = ConvertUtils.sourceToTarget(signEntity, QuerySignResp.class);
			resp.setAmount(MoneyUtil.bigDecimal2String(signEntity.getAmount(), 2));
			//显示金额=实际金额+机器人金额
			BigDecimal total = signEntity.getReward().add(signEntity.getRewardj());
			resp.setReward(MoneyUtil.bigDecimal2String(total, 2));
			//显示人数=实际人数+机器人数
			resp.setSignCount(signEntity.getSignCount() + signEntity.getSignCountj());
			list.add(resp);
		}
		log.info("期数列表，返回:{}",JSON.toJSONString(list));
		return list;
	}

	/**
	 * 期数详情
	 */
	@Override
	public QuerySignDetailResp querySignDetail(QuerySignInfoReq dto,YnUserEntity ynuser) {
		//期数
		String year = dto.getSignNo();//ZqDateUtil.yyyyMMdd(ZqDateUtil.getNow());
		log.info("期数详情year：{},dto:{},ynuser:{}",year,JSON.toJSONString(dto),JSON.toJSONString(ynuser));
		//业务类型
		String busType = dto.getBusType();
		if("1".equals(busType)){
			//year = ZqDateUtil.yyyyMMdd(ZqDateUtil.addDate(ZqDateUtil.getNow(), -1, Calendar.DAY_OF_MONTH));
			year = ZqDateUtil.yyyyMMdd(ZqDateUtil.getNow());
		}else if("2".equals(busType)){
			year = ZqDateUtil.yyyyMMdd(ZqDateUtil.getNow());
		}
		//返回结构
		QuerySignDetailResp resp = new QuerySignDetailResp();
		//查询期数
		QueryWrapper<YnSignEntity> wrapper = new QueryWrapper<YnSignEntity>();
		wrapper.eq("sign_no", year);
		wrapper.eq("type", dto.getType());
		YnSignEntity signEntity = baseDao.selectOne(wrapper);
		
		resp = ConvertUtils.sourceToTarget(signEntity, QuerySignDetailResp.class);
		//显示金额=实际金额+机器人金额
		BigDecimal totalReward = signEntity.getReward().add(signEntity.getRewardj());
		resp.setReward(MoneyUtil.bigDecimal2String(totalReward, 2));
		//显示人数=实际人数+机器人数
		resp.setSignCount(signEntity.getSignCount() + signEntity.getSignCountj());
		resp.setAmount(MoneyUtil.bigDecimal2String(signEntity.getAmount(), 2));
		resp.setOpenTime("08:00:00");
		
		String time = signEntity.getSignTime();
		String startTime = time.split("#")[0];
		String endTime = time.split("#")[1];

		//登录后查询用户累计瓜分，累计挑战，未读挑战
		if(ynuser != null && ynuser.getId() != null){
			//查询累计瓜分金额
			List<YnSignRecordEntity> signRecord = ynSignRecordService.queryUserSign(null, null, ynuser.getId(),null);
			BigDecimal totalIncome = BigDecimal.ZERO;
			for(YnSignRecordEntity sign : signRecord){
				totalIncome = totalIncome.add(sign.getAmount());
			}
			resp.setTotalIncome(MoneyUtil.bigDecimal2String(totalIncome, 2));
			//我的挑战未读数量
			List<YnSignRecordEntity> signRecord1 = ynSignRecordService.queryUserSign(null, null, ynuser.getId(),"0");
			//0：挑战中，1：挑战成功，2：挑战失败
			int tipNum0 = 0,tipNum1 = 0;
			for(YnSignRecordEntity e1 : signRecord1){
				if("0".equals(e1.getStatus())){
					tipNum0 ++ ;
				}else if("2".equals(e1.getStatus())){
					tipNum1 ++ ;
				}
			}
			resp.setTipNum0(tipNum0);
			resp.setTipNum1(tipNum1);
			resp.setMySignNum(signRecord1.size()+"");
			//我的总挑战次数
			resp.setSignTotalNum(signRecord.size()+"");
			//查询当前期数用户挑战状态
			List<YnSignRecordEntity> signRecord2 = ynSignRecordService.queryUserSign(year, dto.getType(), ynuser.getId(),null);
			//本期参与状态(0立即挑战，1等待打卡，2立即打卡,3等待派奖，4挑战成功，5挑战失败)
			if(signRecord2 != null && signRecord2.size() > 0){
				YnSignRecordEntity entity = signRecord2.get(0);
				//更新已读
				if("3".equals(busType)){
					YnSignRecordEntity entity1 = new YnSignRecordEntity();
					entity1.setId(entity.getId());
					entity1.setYesnoRead("1");
					entity1.setUpdateDate(ZqDateUtil.getNow());
					ynSignRecordService.updateById(entity1);
				}
				
				Date now = ZqDateUtil.getNow();
				//当前时间在打卡时间段内
				if(now.compareTo(ZqDateUtil.getDatehms(startTime)) < 0 ){
					resp.setSignStatus("1");
				}else if(now.compareTo(ZqDateUtil.getDatehms(startTime)) >= 0 && now.compareTo(ZqDateUtil.getDatehms(endTime)) <= 0){
					//未打过卡
					if(entity.getSignTime() == null){
						resp.setSignStatus("2");
						//查询剩余打卡名额
						List<YnSignRecordEntity> signRecord3 = ynSignRecordService.queryUserSign(year, dto.getType(), null,null);
						if(signRecord3 != null && signRecord3.size() > 0){
							//总名额（总名额是报名数量的60%）
							BigDecimal total = new BigDecimal(signRecord3.size()).multiply(new BigDecimal(0.6));
							//四舍五入
							String userNum = MoneyUtil.bigDecimal2String(total, 0);
							//计算出已打卡人数
							int ydk = 0;
							for(YnSignRecordEntity sign : signRecord3){
								if(sign.getSignTime() != null){
									ydk ++ ;
								}
							}
							resp.setSignNumSy((Integer.parseInt(userNum) - ydk)+"");
						}
					}else{
						resp.setSignStatus("3");
					}
				}else if(now.compareTo(ZqDateUtil.getDatehms(endTime)) > 0 ){
					//未打过卡
					if(entity.getSignTime() == null){
						resp.setSignStatus("5");
					}else{
						resp.setSignStatus("4");
						resp.setReward(MoneyUtil.bigDecimal2String(entity.getAmount(), 2));
					}
				}
			}else {
				resp.setSignStatus("0");
			}
		}else{
			//本期参与状态(0立即挑战，1等待打卡，2立即打卡,3等待派奖，4挑战成功，5挑战失败)
			resp.setSignStatus("0");
		}
		//倒计时计算（返回毫秒）
		if("1".equals(resp.getSignStatus())){
			Date sign = ZqDateUtil.getDatehms(startTime);
			Long t1 = sign.getTime() - ZqDateUtil.getNow().getTime();
			if(t1 < 0){
				t1 = 0l;
			}
			resp.setSignTimeh(t1+"");
		}else if("3".equals(resp.getSignStatus())){
			Date sign = ZqDateUtil.getDatehms(endTime.split(" ")[0]+" "+resp.getOpenTime());
			Long t1 = sign.getTime() - ZqDateUtil.getNow().getTime();
			if(t1 < 0){
				t1 = 0l;
			}
			resp.setOpenTimeh(t1+"");
		}
		//返回未打卡等级
		List<YnSignRecordEntity> noSignRecord = ynSignRecordService.queryUserSign(year, null, ynuser.getId(),null);
		List<String> level = new ArrayList<String>();
		for(YnSignRecordEntity rec : noSignRecord){
			level.add(rec.getType());
		}
		List<String> noLevel = new ArrayList<String>();
		for(int i = 1;i<= 4;i++){
			if(!level.contains(i+"")){
				noLevel.add(i+"");
			}
		}
		resp.setNoSignLevel(noLevel);
		//榜单之最
		List<BeatSignResp> list = new ArrayList<BeatSignResp>();
		
		BeatSignResp resp1 = ynSignRecordService.bestTime(year, dto.getType());
		BeatSignResp resp2 = ynSignRecordService.bestMoney(year, dto.getType());
		BeatSignResp resp3 = ynSignRecordService.bestNum(year, dto.getType());
		if(resp1 != null){
			list.add(resp1);
		}
		if(resp2 != null){
			list.add(resp2);
		}
		if(resp3 != null){
			list.add(resp3);
		}
		resp.setList(list);
		log.info("期数详情，返回:{}",JSON.toJSONString(resp));
		return resp;
	}
	/**
	 * 挑战
	 */
	@Override
	public void preSign(QuerySignInfoReq dto, YnUserEntity ynuser) {
		log.info("挑战，参数dto:{},ynuser:{}",JSON.toJSONString(dto),JSON.toJSONString(ynuser));
		String signNo = dto.getSignNo();
		String type = dto.getType();
		//当前期数
		String nowSignNo = ZqDateUtil.yyyyMMdd(ZqDateUtil.getNow());
		//判断是否对应
		/*if(!nowSignNo.equals(signNo)){
			throw new RenException(ErrorCode.PARAM_ERROR);
		}*/
		
		//查询是否已经参加过
		List<YnSignRecordEntity> list = ynSignRecordService.queryUserSign(nowSignNo, type, ynuser.getId(), null);
		if(list != null && list.size() > 0){
			throw new RenException(ErrorCode.SIGN_IS_EXIST);
		}
		//查询期数
		QueryWrapper<YnSignEntity> wrapper = new QueryWrapper<YnSignEntity>();
		wrapper.eq("sign_no", nowSignNo);
		wrapper.eq("type", type);
		YnSignEntity signEntity = baseDao.selectOne(wrapper);
		BigDecimal amount = signEntity.getAmount();
		//判断余额
		if(ynuser.getBalance().compareTo(amount) < 0){
			throw new RenException(ErrorCode.AMOUNT_IS_LESS);
		}
		//判断是否在活动时间内
		String time = signEntity.getEnterTime();
		String startTime = time.split("#")[0];
		String endTime = time.split("#")[1];
		Date now = ZqDateUtil.getNow();
		//当前时间在活动时间段内
		if(now.compareTo(ZqDateUtil.getDatehms(startTime)) < 0){
			throw new RenException(ErrorCode.LOTTERY_TIME_MIN);
		}
		if(now.compareTo(ZqDateUtil.getDatehms(endTime)) > 0){
			throw new RenException(ErrorCode.LOTTERY_TIME_MAX);
		}

		//添加挑战记录
		YnSignRecordEntity re = new YnSignRecordEntity();
		re.setSignId(signEntity.getId());
		re.setSignNo(nowSignNo);
		re.setUserId(ynuser.getId());
		re.setType(type);
		re.setStatus("0");
		re.setCreateDate(ZqDateUtil.getNow());
		ynSignRecordService.insert(re);
		//计算奖池
		BigDecimal reward = amount.add(signEntity.getReward());
		BigDecimal platform_fee = amount.multiply(new BigDecimal(0.2)).add(signEntity.getPlatformFee());
		
		BigDecimal distribute_amount = amount.multiply(new BigDecimal(0.8));
		BigDecimal cashout_amount = distribute_amount.multiply(new BigDecimal(0.1));
		
		BigDecimal distribute_amount1 = distribute_amount.subtract(cashout_amount).add(signEntity.getDistributeAmount());
		BigDecimal cashout_amount1 = cashout_amount.add(signEntity.getCashoutAmount());
		//更新奖池
		YnSignEntity en1 = new YnSignEntity();
		en1.setId(signEntity.getId());
		en1.setReward(reward);
		en1.setPlatformFee(platform_fee);
		en1.setDistributeAmount(distribute_amount1);
		en1.setCashoutAmount(cashout_amount1);
		en1.setSignCount(signEntity.getSignCount() + 1);
		baseDao.updateById(en1);
		//交易记录
		ynPayRecordService.payrecord(ynuser.getId(),null,"SIGNOUT","bank",amount,"打卡金额");
		//更新账户记录
		YnUserEntity user = new YnUserEntity();
		BigDecimal balance = ynuser.getBalance().subtract(amount);
		user.setId(ynuser.getId());
		user.setBalance(balance);
		user.setChallenge(ynuser.getChallenge() + 1);
		user.setUpdateDate(ZqDateUtil.getNow());
		ynUserService.updateById(user);

	}
	/**
	 * 打卡
	 */
	@Override
	public void sign(SignReq dto, YnUserEntity ynuser) {
		log.info("打卡，参数dto:{},ynuser:{}",JSON.toJSONString(dto),JSON.toJSONString(ynuser));
		String type = dto.getType();
		//打卡昨天的期数
		String yyyyMMdd = ZqDateUtil.yyyyMMdd(ZqDateUtil.addDate(ZqDateUtil.getNow(), -1, Calendar.DAY_OF_MONTH));
		//查询是否已经打卡
		List<YnSignRecordEntity> list = ynSignRecordService.queryUserSign(yyyyMMdd, type, ynuser.getId(), null);
		//挑战记录
		YnSignRecordEntity rec = null;
		if(list != null && list.size() > 0){
			rec = list.get(0);
			if(rec.getSignTime() != null){
				throw new RenException(ErrorCode.SIGN_IS_EXIST);
			}
		}
		//查询期数
		QueryWrapper<YnSignEntity> wrapper = new QueryWrapper<YnSignEntity>();
		wrapper.eq("sign_no", yyyyMMdd);
		wrapper.eq("type", type);
		YnSignEntity signEntity = baseDao.selectOne(wrapper);

		//判断是否在活动时间内
		String time = signEntity.getSignTime();
		String startTime = time.split("#")[0];
		String endTime = time.split("#")[1];
		Date now = ZqDateUtil.getNow();
		//当前时间在活动时间段内
		if(now.compareTo(ZqDateUtil.getDatehms(startTime)) < 0){
			throw new RenException(ErrorCode.LOTTERY_TIME_MIN);
		}
		if(now.compareTo(ZqDateUtil.getDatehms(endTime)) > 0){
			throw new RenException(ErrorCode.LOTTERY_TIME_MAX);
		}
		//判断人数是否满额
		int balanceNum = 0;
		//查询剩余打卡名额
		List<YnSignRecordEntity> signRecord3 = ynSignRecordService.queryUserSign(yyyyMMdd, type, null,null);
		if(signRecord3 != null && signRecord3.size() > 0){
			//总名额（总名额是报名数量的60%）
			BigDecimal total = new BigDecimal(signRecord3.size()).multiply(new BigDecimal(0.6));
			//四舍五入
			String userNum = MoneyUtil.bigDecimal2String(total, 0);
			//计算出已打卡人数
			int ydk = 0;
			for(YnSignRecordEntity sign : signRecord3){
				if(sign.getSignTime() != null){
					ydk ++ ;
				}
			}
			balanceNum = Integer.parseInt(userNum) - ydk;
		}
		if(balanceNum <= 0){
			throw new RenException(ErrorCode.FULL_SIGN);
		}
		//更新报名记录
		YnSignRecordEntity re = new YnSignRecordEntity();
		re.setId(rec.getId());
		re.setSignTime(ZqDateUtil.getNow());
		re.setStatus("1");
		re.setUpdateDate(ZqDateUtil.getNow());
		ynSignRecordService.updateById(re);
	}
}